#include "wuEnte.h"

wuEnte::wuEnte()
{
}

wuEnte::~wuEnte()
{
}

void wuEnte::setup(ofxBox2d * _box2d, int _vw, int _vh, int _initX, int _initY){
    box2d = _box2d;

	initPos.x = _initX;
	initPos.y = _initY;

    vw = _vw;
    vh = _vh;

//  simpleAmount = 15.0;
   	simpleAmount = 1.0;

//	contourAnalysis.setSize(vw, vh);

	grayDiff.clear();
	grayDiff.allocate(vw, vh);

	bTouched = false;
    bGravity = true;

	basedim = 25; // base size

	// create rectangle base
	base.setPhysics(0.01, 0.0, 10.0031);
	base.setup(box2d->getWorld(), initPos.x, initPos.y, basedim, basedim);

	// set texture-mix
	myFBO.allocate(vw, vh, GL_RGBA);
	myFBO.clear(0, 0, 0, 0);

	framePos.x = 0;
	framePos.y = 0;
	shapeOff.x = 0;
	shapeOff.y = 0;
	scale.x = scale.y = 1.0;
    scrollOffset=0;

}


void wuEnte::setContourAmount(int _simpleAmount){
   	simpleAmount = _simpleAmount;
}

void wuEnte::update()
{
    if(!bGravity)
       base.setVelocity(0,0);

	FindShape(&grayDiff);
}

void wuEnte::draw_lines()
{
		ofSetColor(255, 255, 255);

		// box2dRect base
		base.draw();

		// kinect frame
        ofNoFill();
		ofRect(rect.x, rect.y, rect.width, rect.height);

		ofSetColor(0,255,255);
//	    for(int i=0; i<lineStrips.size(); i++)
//			lineStrips[i].draw();

        polyLine.draw();
}

void wuEnte::draw_FBO(int _x, int _y)
{
	ofPushMatrix();
		ofEnableAlphaBlending();
		ofSetColor(255, 255, 255, 255);
		myFBO.draw(_x,_y);
		ofDisableAlphaBlending();
	ofPopMatrix();
}

void wuEnte::FindShape(wuGrayImg * _grayDiff)
{
		    ofPoint p;
			p = base.getPosition();

		    contour.blobs.clear();
			contour.findContours(*_grayDiff, 20, (vw*vh), 10, false);	// find holes

            polyLine.clear();
/*		    for(int i=0; i<lineStrips.size(); i++)
			{
				lineStrips[i].clear();
			}
			lineStrips.clear();
*/
            if(contour.nBlobs > 0){

//                contourAnalysis.simplify(contour.blobs[0].pts, simpleCountour, simpleAmount);

				// rectangle al voltant de l' enanito
                rect.x = contour.blobs[0].boundingRect.x;
                rect.y = contour.blobs[0].boundingRect.y;
                rect.width = contour.blobs[0].boundingRect.width;
                rect.height = contour.blobs[0].boundingRect.height;

				if(!bTouched)
				{
                    // make the shape
                    if(contour.blobs[0].pts.size()>2)
                    {
                       for(int j=contour.blobs[0].pts.size()/2; j<contour.blobs[0].pts.size(); j++) {
                            if (contour.blobs[0].pts[j].y < p.y - basedim/2 -15)
                                polyLine.addVertex(contour.blobs[0].pts[j].x+scrollOffset, contour.blobs[0].pts[j].y);
                        }
                       for(int j=0; j<contour.blobs[0].pts.size()/2; j++) {
                            if (contour.blobs[0].pts[j].y < p.y - basedim/2 -15)
                                polyLine.addVertex(contour.blobs[0].pts[j].x+scrollOffset, contour.blobs[0].pts[j].y);
                        }
                        if(polyLine.isGoodShape())
                        {
                            // at least 3 points (treure el simplify si es queixa)
                            polyLine.simplify(5.0);
                            polyLine.setPhysics(0.0, 0.5, 0.5);
                            polyLine.create(box2d->getWorld());
                        }

                    }


/*
//					ofxBox2dLine lineStrip;

					for(int j=simpleCountour.size()-1; j>-1; j--) {
						if (simpleCountour[j].y < p.y - basedim/2 -15)
						    lineStrip.addPoint(simpleCountour[j].x+shapeOff.x, simpleCountour[j].y+shapeOff.y);
					}

					lineStrip.setWorld(box2d->getWorld());
					lineStrip.setElasticity(0.);
					lineStrip.createShape();
					lineStrips.push_back(lineStrip);
*/
				}
				bTouched = false;

			}
}

/*void wuEnte::FindShape(wuGrayImg * _grayDiff)
{
		    ofPoint p;
			p = base.getPosition();

		    contour.blobs.clear();
			contour.findContours(*_grayDiff, 20, (vw*vh), 10, false);	// find holes

		    for(int i=0; i<lineStrips.size(); i++)
			{
				lineStrips[i].clear();
			}
			lineStrips.clear();

            if(contour.nBlobs > 0){

                contourAnalysis.simplify(contour.blobs[0].pts, simpleCountour, simpleAmount);

				// rectangle al voltant de l' enanito
                rectX = contour.blobs[0].boundingRect.x*scaleX;
                rectY = contour.blobs[0].boundingRect.y*scaleY;
                rectW = contour.blobs[0].boundingRect.width*scaleX;
                rectH = contour.blobs[0].boundingRect.height*scaleY;

				if(!bTouched)
				{
					ofxBox2dLine lineStrip;

					for(int j=simpleCountour.size()-1; j>-1; j--) {
						if (simpleCountour[j].y*scaleX+kinFrameY < p.y - basedim/2 -15)
						    lineStrip.addPoint(simpleCountour[j].x*scaleX+kinFrameX, simpleCountour[j].y*scaleY+kinFrameY);
					}
					lineStrip.setWorld(box2d->getWorld());
					lineStrip.setElasticity(0.);
					lineStrip.createShape();
					lineStrips.push_back(lineStrip);
				}
				bTouched = false;

			}
}
*/
bool wuEnte::isTouched(int _x,int _y)
{
	if( (_x > rect.x) && (_x < rect.x+rect.width) && (_y > rect.y) && (_y < rect.y+rect.height) )
		bTouched = true;
	else
		bTouched = false;

	return bTouched;
}

void wuEnte::Touch(int _x,int _y, int forceX, int forceY)
{
	ofPoint p;
	p = base.getPosition();

	if( (_x > rect.x) && (_x < rect.x+rect.width) && (_y > rect.y) && (_y < rect.y+rect.height) )
	{
		if(forceX > 0)
		{
			if( (_x > rect.x) && (_x < rect.x+rect.width/2))
				base.addImpulseForce(ofPoint(rect.x,p.y), ofPoint(forceX,0));
			if( (_x > rect.x+rect.width/2) && (_x < rect.x+rect.width))
				base.addImpulseForce(ofPoint(rect.x+rect.width,p.y), ofPoint(0-forceX,0));
		}
		if(forceY > 0)
		{
			if( (_y > rect.y) && (_y < rect.y+rect.height/2) )
				base.addImpulseForce(ofPoint(p.x,rect.y), ofPoint(0,0-forceY));
			if( (_y > rect.y+rect.height/2) && (_y < rect.y+rect.height) )
				base.addImpulseForce(ofPoint(p.x,rect.y+rect.height), ofPoint(0,forceY));
		}
	}
}

void wuEnte::setPosition(int _x,int _y)
{
		base.setPosition(_x,_y);
}

ofPoint wuEnte::getPosition()
{
	return base.getPosition();
}

void wuEnte::myFBO_begin()
{
	myFBO.clear(0, 0, 0, 0);

	myFBO.begin();
//	ofClear(0,0,0,0); //no more autoclear
	glClearColor(0, 0, 0, 0);
}

void wuEnte::myFBO_end()
{
	myFBO.end();

	grayDiff.setFromAlphaPixels((unsigned char *)myFBO.getPixels(), vw, vh, true);
//	ofPixels pixels;
//   myFBO.readToPixels(pixels);
//	grayDiff.setFromAlphaPixels(pixels.getPixels(), vw, vh, true);
	grayDiff.blur(9);
}
void wuEnte::setGravity(bool _bGravity)
{
    bGravity = _bGravity;
}

void wuEnte::clear()
{
    polyLine.clear();
    polyLine.destroy();
    base.destroy();
    myFBO.clear(0, 0, 0, 0);
}

bool wuEnte::drag(int _x,int _y)
{
    bool bDrag=false;
	if ((_x > rect.x) && (_x < rect.x+rect.width) && (_y > rect.y) && (_y < rect.y+rect.height))
	{
	    setPosition(_x, _y);
	    bDrag=true;
	}

   return bDrag;
}

void wuEnte::setScrollOffset(int _scrollOff)
{
    scrollOffset = _scrollOff;
}
